package io.kiki.sba.registry.server.data_store.multi.cluster.slot;

import io.prometheus.client.Counter;
import io.prometheus.client.Gauge;
import io.prometheus.client.Histogram;


public class MultiClusterSlotMetrics {
    private static final Gauge REMOTE_LEADER_ASSIGN_GAUGE = Gauge.build().namespace("data").subsystem("slot").name("remote_leader_assign_total").help("leader assign").labelNames("dataCenter").register();
    private static final Histogram REMOTE_LEADER_SYNCING_HISTOGRAM = Histogram.build().namespace("data").subsystem("slot").name("remote_leader_syncing_secs").help("syncing in seconds.").labelNames("dataCenter", "slot").buckets(3, 5, 10, 20, 30, 60, 120, 180, 240).register();
    private static final Gauge REMOTE_LEADER_SYNCING_GAUGE = Gauge.build().namespace("data").subsystem("slot").name("remote_leader_syncing_total").help("count remote leader is syncing").labelNames("dataCenter", "slot").register();
    private static final Counter SYNC_COUNTER = Counter.build().namespace("data").subsystem("access").name("sync_total").labelNames("remote", "type").help("sync data access num").register();

    private MultiClusterSlotMetrics() {
    }

    static void observeRemoteLeaderAssignGauge(String dataCenter, int num) {
        REMOTE_LEADER_ASSIGN_GAUGE.labels(dataCenter).set(num);
    }

    static void observeRemoteLeaderSyncingStart(String dataCenter, int slotId) {
        REMOTE_LEADER_SYNCING_GAUGE.labels(dataCenter, String.valueOf(slotId)).set(1);
    }

    static void observeRemoteLeaderSyncingFinish(String dataCenter, int slotId) {
        REMOTE_LEADER_SYNCING_GAUGE.labels(dataCenter, String.valueOf(slotId)).set(0);
    }

    static void observeRemoteLeaderSyncingHistogram(String dataCenter, int slotId, long millis) {
        REMOTE_LEADER_SYNCING_HISTOGRAM.labels(dataCenter, String.valueOf(slotId)).observe(millis / 1000d);
    }

    public static void syncAccess(String remote, SyncType syncType) {
        if (syncType == SyncType.sync_all) {
            SYNC_COUNTER.labels(remote, "ALL").inc();
        } else
            if (syncType == SyncType.sync_delta) {
                SYNC_COUNTER.labels(remote, "DELTA").inc();
            } else {
                throw new IllegalArgumentException("illegal sync type: " + syncType);
            }
    }

    public enum SyncType {
        sync_all, sync_delta,
        ;
    }

    public static final class RemoteSyncLeader {
        private static final Counter REMOTE_SYNC_LEADER_ID_COUNTER = Counter.build().namespace("data").subsystem("sync").name("remote_leader_id_total").help("count remote sync leader dataInfoIds").labelNames("dataCenter", "slot").register();

        private static final Counter REMOTE_SYNC_LEADER_ID_NUM_COUNTER = Counter.build().namespace("data").subsystem("sync").name("remote_leader_id_num_total").help("count remote sync leader dataInfoId's num").labelNames("dataCenter", "slot").register();

        private static final Counter REMOTE_SYNC_LEADER_PUB_COUNTER = Counter.build().namespace("data").subsystem("sync").name("remote_leader_pub_total").help("count remote sync leader pubs").labelNames("dataCenter", "slot").register();

        private static final Counter REMOTE_SYNC_LEADER_PUB_NUM_COUNTER = Counter.build().namespace("data").subsystem("sync").name("remote_leader_pub_num_total").help("count remote sync leader pub's num").labelNames("dataCenter", "slot").register();

        public static void observeSyncLeaderId(String dataCenter, int slotId, int idNum) {
            final String str = String.valueOf(slotId);
            REMOTE_SYNC_LEADER_ID_COUNTER.labels(dataCenter, str).inc();
            REMOTE_SYNC_LEADER_ID_NUM_COUNTER.labels(dataCenter, str).inc(idNum);
        }

        public static void observeSyncLeaderPub(String dataCenter, int slotId, int pubNum) {
            final String str = String.valueOf(slotId);
            REMOTE_SYNC_LEADER_PUB_COUNTER.labels(dataCenter, str).inc();
            REMOTE_SYNC_LEADER_PUB_NUM_COUNTER.labels(dataCenter, str).inc(pubNum);
        }
    }
}
